package com.yf.exam.modules.user.cert.service.impl;

import com.yf.exam.ability.job.enums.JobGroup;
import com.yf.exam.ability.job.service.JobService;
import com.yf.exam.modules.user.cert.job.CertCleanupJob;
import com.yf.exam.modules.user.cert.job.CertRetryJob;
import com.yf.exam.modules.user.cert.service.CertScheduleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * 证书定时任务管理服务实现
 * 
 * @author Q_include
 */
@Slf4j
@Service
public class CertScheduleServiceImpl implements CertScheduleService, ApplicationRunner {

    @Autowired
    private JobService jobService;

    // 任务名称常量
    private static final String CERT_RETRY_JOB_NAME = "CERT_RETRY_JOB";
    private static final String CERT_CLEANUP_JOB_NAME = "CERT_CLEANUP_JOB";

    // 默认cron表达式 - 生产环境频率
    private static final String DEFAULT_RETRY_CRON = "0 0 * * * ?"; // 每小时执行一次
    private static final String DEFAULT_CLEANUP_CRON = "0 0 2 * * ?"; // 每天凌晨2点执行

    @Override
    public void startCertRetrySchedule() {
        startCertRetrySchedule(DEFAULT_RETRY_CRON);
    }

    @Override
    public void startCertRetrySchedule(String cron) {
        try {
            if (StringUtils.isEmpty(cron)) {
                cron = DEFAULT_RETRY_CRON;
            }
            
            log.info("启动证书失败重试定时任务，cron表达式：{}", cron);
            
            jobService.addCronJob(
                CertRetryJob.class,
                CERT_RETRY_JOB_NAME,
                cron,
                "证书失败重试任务"
            );
            
            log.info("证书失败重试定时任务启动成功");
            
        } catch (Exception e) {
            log.error("启动证书失败重试定时任务失败", e);
        }
    }




    @Override
    public void startCertCleanupSchedule() {
        startCertCleanupSchedule(DEFAULT_CLEANUP_CRON);
    }

    @Override
    public void startCertCleanupSchedule(String cron) {
        try {
            if (StringUtils.isEmpty(cron)) {
                cron = DEFAULT_CLEANUP_CRON;
            }
            
            log.info("启动证书资源清理定时任务，cron表达式：{}", cron);
            
            jobService.addCronJob(
                CertCleanupJob.class,
                CERT_CLEANUP_JOB_NAME,
                cron,
                "证书资源清理任务"
            );
            
            log.info("证书资源清理定时任务启动成功");
            
        } catch (Exception e) {
            log.error("启动证书资源清理定时任务失败", e);
        }
    }

    @Override
    public void stopScheduledTask(String jobName, String jobGroup) {
        try {
            if (StringUtils.isEmpty(jobGroup)) {
                jobGroup = JobGroup.SYSTEM;
            }
            
            log.info("停止定时任务：{}/{}", jobGroup, jobName);
            
            jobService.pauseJob(jobName, jobGroup);
            jobService.deleteJob(jobName, jobGroup);
            
            log.info("定时任务停止成功：{}/{}", jobGroup, jobName);
            
        } catch (Exception e) {
            log.error("停止定时任务失败：{}/{}", jobGroup, jobName, e);
        }
    }

    @Override
    public void initDefaultSchedules() {
        try {
            log.info("初始化证书相关默认定时任务");
            
            // 启动失败重试任务（每小时执行一次）
            startCertRetrySchedule();
            
            // 启动资源清理任务（每天凌晨2点执行）
            startCertCleanupSchedule();
            
            log.info("证书相关默认定时任务初始化完成");
            
        } catch (Exception e) {
            log.error("初始化证书相关默认定时任务失败", e);
        }
    }

    /**
     * 应用启动后自动初始化默认定时任务
     */
    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("应用启动完成，开始初始化证书定时任务");
        
        // 延迟30秒启动，确保所有Bean都已初始化完成
        new Thread(() -> {
            try {
                Thread.sleep(30000); // 延迟30秒
                initDefaultSchedules();
            } catch (InterruptedException e) {
                log.warn("定时任务初始化线程被中断", e);
                Thread.currentThread().interrupt();
            } catch (Exception e) {
                log.error("定时任务初始化失败", e);
            }
        }).start();
    }
}